import com.microsoft.playwright.*;
import com.microsoft.playwright.options.LoadState;
import com.microsoft.playwright.options.WaitForSelectorState;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PlaywrightExample {

    // 使用静态变量管理Playwright和Browser实例
    private static Playwright playwright;
    private static Browser browser;
    static ConcurrentHashMap<String, Page> pageMaps = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        try {
            // 初始化Playwright和Browser
            playwright = Playwright.create();
            browser = playwright.chromium().launch(
                    new BrowserType.LaunchOptions().setHeadless(false).setChannel("chrome")
            );

            login("lijd615", "Wdnmdzz00.");
            System.out.println("按任意键退出...");
            System.in.read();
            playwright.close();
            browser.close();
            closePage();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            pageMaps.values().forEach(Page::close);
            if (browser != null) browser.close();
            if (playwright != null) playwright.close();
        }
    }

    private static void closePage() {
        for (Page value : pageMaps.values()) {
            value.close();
        }
    }

    public static void login(String account, String password) throws IOException {
        Page page = pageMaps.get(account);
        if (page == null) {
            page = createPageAccount(account);
        }
        page.navigate("https://sia.sinopec.com/page/#/college/index");
        page.waitForSelector(".login-btn").click();

        // 输入账号
        page.waitForSelector("input[placeholder='请输入统一账号']").fill(account);

        // 输入密码（增强版）
        page.waitForSelector("input[placeholder='请输入密码']",
                new Page.WaitForSelectorOptions().setState(WaitForSelectorState.VISIBLE));
        page.locator("input[placeholder='请输入密码']").click();
        page.locator("input[placeholder='请输入密码']").clear();
        page.locator("input[placeholder='请输入密码']").fill(password);

        // 点击登录按钮
        page.waitForSelector("button:has-text('立即登录')").click();

        page.locator(".quantity .list .item").nth(4).click();
        page.waitForSelector(".studyContent .content .table ul li");
        List<Locator> allClass = page.locator(".studyContent .content .table ul li").all();
        for (Locator classData : allClass) {
            Locator h4 = classData.locator("h4");
            String startTime = timeFilter(classData.locator("p").nth(0).textContent());
            String endTime = timeFilter(classData.locator("p").nth(1).textContent());
            System.out.println("开始时间：" + startTime);
            System.out.println(h4.textContent());
            System.out.println("结束时间：" + endTime);
            Locator enterButton = classData.locator(".btn:has-text('进入')"); // 定位“进入”按钮
            enterButton.click();
            //弹窗确认
            alertWindow(page);
            // 读取 JavaScript 脚本文件内容
            String scriptContent = new String(Files.readAllBytes(Paths.get("lib/wl.js")));

            // 定义期望分数
            int targetScore = 90;
            scriptContent =  modifyScriptForTargetScore(scriptContent, targetScore);


            Page currentActivePage = getCurrentActivePage(account);
            System.out.println(currentActivePage.url());
            assert currentActivePage != null;
            currentActivePage.waitForLoadState(LoadState.NETWORKIDLE);
            Object evaluate = currentActivePage.evaluate(scriptContent);
            System.out.println(evaluate);
            break;
        }

    }
    /**
     * 获取指定账号对应的浏览器上下文中的当前活动页面
     * @param account 账号
     * @return 当前活动页面，如果未找到则返回null
     */
    public static Page getCurrentActivePage(String account) {
        Page mainPage = pageMaps.get(account);
        if (mainPage == null) {
            System.err.println("未找到账号对应的主页面: " + account);
            return null;
        }

        BrowserContext context = mainPage.context();
        List<Page> pages = context.pages();

        if (pages.isEmpty()) {
            System.err.println("上下文中没有打开的页面");
            return null;
        }

        // 返回最后一个打开的页面（通常是当前活动页面）
        return pages.get(pages.size() - 1);
    }
    public static void sleepAuto(int m){
        try {
            Thread.sleep(2000*m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 替换分数
     *
     * @param script
     * @param targetScore
     * @return
     */
    private static String modifyScriptForTargetScore(String script, int targetScore) {
        // 移除原有的分数区间设置
        script = script.replace("const targetScore = 80;", "const targetScore = "+targetScore+";");
        return script;
    }

    /**
     * 点击弹窗确认
     *
     * @param page
     */
    public static void alertWindow(Page page) {
        // 定义确认按钮的Locator，使用更精确的选择器
        Locator confirmButton = page.locator(".conteneDlg .btn button:has-text('确认')");

        try {
            // 等待确认按钮出现并可点击（默认超时30秒）
            confirmButton.waitFor(new Locator.WaitForOptions().setTimeout(1500)
                    .setState(WaitForSelectorState.VISIBLE));

            // 点击确认按钮前添加日志
            System.out.println("确认按钮已找到，准备点击");

            // 使用force选项确保点击（处理覆盖层等特殊情况）
            confirmButton.click(new Locator.ClickOptions().setForce(true));

            System.out.println("成功点击确认按钮");
        } catch (TimeoutError e) {
            // 超时处理：确认按钮未在指定时间内出现
            System.out.println("确认按钮未在30秒内出现或不可点击");
        }

    }

    /**
     * 时间过滤
     *
     * @param textTime 需要过滤的包含时间的字符串
     * @return
     */
    public static String timeFilter(String textTime) {
        // 正则表达式匹配时间格式
        Pattern pattern = Pattern.compile(":\\s*(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2})");
        Matcher matcher = pattern.matcher(textTime);
        if (matcher.find()) {
            System.out.println(matcher.group(1));
            return matcher.group(1);
        }
        return null;
    }

    /**
     * 创建一个page
     *
     * @param account 账号
     * @return
     */
    public static Page createPageAccount(String account) {
        try {
            // 使用已初始化的browser创建上下文和页面
            BrowserContext context = browser.newContext(new Browser.NewContextOptions()
                    .setJavaScriptEnabled(true)); // 启用JavaScript支持
            Page page = context.newPage();
            pageMaps.put(account, page);
            return page;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}